<template>
  <main class="login">
    <h1>Plase login to continue</h1>
    <SmartForm class="form" :title="title" :operation="operation" :valid="valid">
      <FormInput name="username" v-model="username" placeholder="Username"></FormInput>
      <FormInput name="password" type="password" v-model="password" placeholder="Password"></FormInput>
      <template v-if="mode === 'signup'">
        <FormInput
          name="verify-password"
          type="password"
          v-model="password2"
          placeholder="Retype Password"
          :invalid="retypePasswordError"
        ></FormInput>
        <FormInput name="email" type="email" v-model="email" placeholder="Email"></FormInput>
      </template>
      <template slot="actions">
        <template v-if="mode === 'login'">
          <button type="button" class="secondary" @click="mode = 'signup'">Sign up</button>
          <button type="submit" :disabled="!valid">Login</button>
        </template>
        <template v-else-if="mode === 'signup'">
          <button type="button" class="secondary" @click="mode = 'login'">Back to login</button>
          <button type="submit" :disabled="!valid">Create account</button>
        </template>
      </template>
    </SmartForm>
  </main>
</template>

<script>
export default {
  data() {
    return {
      mode: "login",
      username: "",
      password: "",
      password2: "",
      email: ""
    };
  },
  computed: {
    title() {
      switch (this.mode) {
        case "login":
          return "Login";
        case "signup":
          return "Create a new account";
      }
    },
    // 校验两次密码输入是否相同
    retypePasswordError() {
      return this.password2 && this.password !== this.password2;
    },
    signupValid() {
      return this.password2 && this.email && !this.retypePasswordError;
    },
    valid() {
      return (
        this.username &&
        this.password &&
        (this.mode !== "signup" || this.signupValid)
      );
    }
  },
  methods: {
    async operation() {
      await this[this.mode]();
    },
    async login() {
      this.$state.user = await this.$fetch("login", {
        method: "POST",
        body: JSON.stringify({
          username: this.username,
          password: this.password
        })
      });
      // 如果用户登录成功，则返回之前浏览的界面，如果没有则返回首页
      this.$router.replace(this.$route.params.wantedRoute || { name: "home" });
    },
    async signup() {
      await this.$fetch("signup", {
        method: "POST",
        body: JSON.stringify({
          username: this.username,
          password: this.password,
          email: this.email
        })
      });
      this.mode = "login";
    }
  }
};
</script>

<style lang="stylus" scoped>
/* 
>>>连结符允许我们将模板中使用的组件内的元素作为目标， 同时仍然限定CSS选择器其余部分的作用域。在我们的例子中， 生成的CSS看起来如下
.form[data-v-0e596401] .content {
     max-width: 400px;
}
如果不使用这个连结符，则会有这样的CSS：
.form .content[data-v-0e596401] {
     max-width: 400px;
} 
*/
.form
  >>> .content
    max-width 400px
</style>